﻿

using Cordyceps.Elasticsearch.Tool.Options;
using Cordyceps.Elasticsearch.Tool.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

namespace Cordyceps.Elasticsearch.Tool.Extensions;


/// <summary>
/// 服务集合扩展方法
/// </summary>
public static class ServiceCollectionExtensions
{
    /// <summary>
    /// 添加Elasticsearch服务到依赖注入容器（从IConfiguration配置）
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="configuration">配置</param>
    /// <param name="sectionName">配置节名称（默认为ElasticsearchOptions.SectionName）</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddElasticsearch(this IServiceCollection services, IConfiguration configuration, string? sectionName = null)
    {
        sectionName ??= ElasticsearchOptions.SectionName;
        
        // 绑定配置到选项
        services.Configure<ElasticsearchOptions>(configuration.GetSection(sectionName));
        
        // 注册Elasticsearch服务
        services.AddSingleton<IElasticsearchService, ElasticsearchService>();
        
        return services;
    }
    
    /// <summary>
    /// 添加Elasticsearch服务到依赖注入容器（使用自定义配置委托）
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="configureOptions">配置选项动作</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddElasticsearch(this IServiceCollection services, Action<ElasticsearchOptions> configureOptions)
    {
        // 注册配置选项
        services.Configure(configureOptions);
        
        // 注册Elasticsearch服务
        services.AddSingleton<IElasticsearchService, ElasticsearchService>();
        
        return services;
    }
    
    /// <summary>
    /// 添加Elasticsearch服务到依赖注入容器（使用配置实例）
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="options">配置选项实例</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddElasticsearch(this IServiceCollection services, ElasticsearchOptions options)
    {
        if (options == null)
            throw new ArgumentNullException(nameof(options));
        
        // 注册配置选项
        services.Configure<ElasticsearchOptions>(opt =>
        {
            opt.Nodes = options.Nodes;
            opt.DefaultIndex = options.DefaultIndex;
            opt.RequestTimeoutSeconds = options.RequestTimeoutSeconds;
            opt.EnableDebugMode = options.EnableDebugMode;
            opt.MaxRetries = options.MaxRetries;
            opt.DisableSslVerification = options.DisableSslVerification;
            opt.ConnectionPoolType = options.ConnectionPoolType;
            opt.EnablePing = options.EnablePing;
            opt.PingIntervalSeconds = options.PingIntervalSeconds;
            opt.EnableClusterAwareness = options.EnableClusterAwareness;
            opt.NodeSelectionStrategy = options.NodeSelectionStrategy;
        });
        
        // 注册Elasticsearch服务
        services.AddSingleton<IElasticsearchService, ElasticsearchService>();
        
        return services;
    }
    
    /// <summary>
    /// 添加Elasticsearch服务到依赖注入容器（使用配置节名称）
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="configuration">配置</param>
    /// <param name="sectionName">配置节名称</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddElasticsearch(this IServiceCollection services, IConfiguration configuration, string sectionName)
    {
        if (configuration == null)
            throw new ArgumentNullException(nameof(configuration));
        
        if (string.IsNullOrEmpty(sectionName))
            throw new ArgumentException("Section name cannot be null or empty", nameof(sectionName));
        
        // 绑定配置到选项
        services.Configure<ElasticsearchOptions>(configuration.GetSection(sectionName));
        
        // 注册Elasticsearch服务
        services.AddSingleton<IElasticsearchService, ElasticsearchService>();
        
        return services;
    }
}